package com.aeasycredit.credit.tuef.manager;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import com.aeasycredit.credit.tuef.constant.TuefSegment;
import com.aeasycredit.credit.tuef.handler.TuefDataHandler;
import com.aeasycredit.credit.tuef.model.TuefHeader;
import com.aeasycredit.credit.tuef.service.TuefHeaderService;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONUtil;

@Component
public class TuefFormatDataBuilder {
    
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Autowired
    private TuefHeaderService tuefHeaderService;
    
    public String build(String tuefBasicId) {
        
        String tuefHeader = this.buildHeader(tuefBasicId);
        logger.info("tuefHeader:{}", tuefHeader);
        
        @SuppressWarnings("rawtypes")
		Collection<TuefDataHandler> handlerList = applicationContext.getBeansOfType(TuefDataHandler.class).values();
        String tuefBody = handlerList.stream().map(handler -> build(tuefBasicId, handler)).collect(Collectors.joining());
        logger.info("tuefBody:{}", tuefBody);
        
        String tuefText = tuefHeader + tuefBody;
        logger.info("tuefText:{}", tuefText);
        return tuefText;
    }
    
    /**
     * 構建指定類型的TUEF格式的文本
     * 
     * @param tuefBasicId TUEF基本信息ID
     * @param handler 處理類
     * @return String TUEF格式的文本
     */
    private String build(String tuefBasicId, TuefDataHandler<?> handler) {
    	Object tuefDataObj = handler.getData(tuefBasicId);
    	return build(handler.supportSegmentFields(), tuefDataObj);
    }
    
    /**
     * 把指定類別的TUEF記錄組裝成TUEF格式的文本
     * 
     * @param tuefSegmentFields TUEF字段信息
     * @param tuefDataObj TUEF記錄
     * @return String TUEF格式的文本
     */
    private String build(TuefSegment[] tuefSegmentFields, Object tuefDataObj) {
        
        if (tuefDataObj instanceof List) {
            @SuppressWarnings("unchecked")
			List<Object> tuefItemDataList = (List<Object>)tuefDataObj;
            return tuefItemDataList.stream()
                .map(tuefItemData -> buildItem(tuefSegmentFields, tuefItemData))
                .collect(Collectors.joining());
        } else {
            return buildItem(tuefSegmentFields, tuefDataObj);
        }
    }
    
    /**
     * 把單條記錄組裝成TUEF格式的文本
     * 
     * @param tuefSegmentFields TUEF字段信息
     * @param itemObj TUEF記錄
     * @return String TUEF格式的文本
     */
    private String buildItem(TuefSegment[] tuefSegmentFields, Object itemObj) {
        logger.info("itemObj:{}", JSONUtil.toJsonStr(itemObj));
        return Stream.of(tuefSegmentFields).map(field -> this.buildFieldTuefText(field, itemObj)).collect(Collectors.joining());
    }
    
    /**
     * 構建指定字段的TEEF格式的文本
     * 
     * @param field TUEF字段信息
     * @param itemObj TUEF記錄
     * @return String 字段的TEEF格式的文本
     */
    private String buildFieldTuefText(TuefSegment field, Object itemObj) {
    	
    	if (Objects.isNull(field.getJavaFieldName())) {
    		return "";
    	}
    	if (StringUtils.equals("segmentTag", field.getJavaFieldName())) {
    		return field.getFieldTag();
    	}
    	
    	Object filedValueObj = ReflectUtil.getFieldValue(itemObj, field.getJavaFieldName());
    	if (Objects.isNull(filedValueObj)) {
    		return "";
    	}
    	
    	String fieldValue = (String)filedValueObj;
        logger.info("fieldTag:{} javaFieldName:{} fieldValue:{}", field.getFieldTag(), field.getJavaFieldName(), fieldValue);
    	return field.getFieldTag() + fieldValue.length() + fieldValue;
    }
    
    /**
     * 構建TUEF格式的頭信息
     * 
     * @param tuefBasicId TUEF基本信息ID
     * @return String TUEF格式的頭信息
     */
    private String buildHeader(String tuefBasicId) {
    	TuefHeader tuefHeader = tuefHeaderService.getByTuefBasicId(tuefBasicId);
    	return buildHeader(tuefHeader);
    }
    
    /**
     * 構建TUEF格式的頭信息
     * 
     * @param tuefHeader 頭信息對象
     * @return String TUEF格式的頭信息
     */
    private String buildHeader(TuefHeader tuefHeader) {
        StringBuilder builder = new StringBuilder();
        builder.append(tuefHeader.getSegmentTag());
        builder.append(tuefHeader.getVersion());
        builder.append(StringUtils.leftPad(tuefHeader.getUserReferenceNumber(), 25, ' '));
        builder.append(StringUtils.leftPad(tuefHeader.getSubscriberCode(), 10, ' '));
        builder.append(tuefHeader.getSubjectReturnCode());
        builder.append(StringUtils.leftPad(tuefHeader.getEnquiryControlNumber(), 9, ' '));
        return builder.toString();
    }
}
